﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using vJine.Core;

namespace vJine.Lua.GUI.BLL {
    public class ProdSpec {
        class SpecRange {
            public double? min{get;set;}
            public double? max {get;set;}
        }

        Dictionary<string, Dictionary<string, SpecRange>> Specs =
            new Dictionary<string, Dictionary<string, SpecRange>>();

        public ProdSpec load(string spec_file) {
            this.Specs.Clear();

            string[] Specs = File.ReadAllLines(spec_file);
            string[] H = Specs[0].Split(',');
            for (int i = 1, len = Specs.Length; i < len; i+=2) {
                string[] mins = Specs[i].Split(',');
                string[] maxs = Specs[i + 1].Split(',');

                string spec_name = mins[0];
                if (string.IsNullOrEmpty(spec_name) || spec_name.StartsWith("-")) {
                    continue;
                }
                Dictionary<string, SpecRange> spec = new Dictionary<string, SpecRange>();

                for (int h = 1, len_h = H.Length; h < len_h; h++) {
                    double? min = null, max = null;
                    string
                        temp_min = mins.Length - 1 < h ? "" : mins[h],
                        temp_max = maxs.Length - 1 < h ? "" : maxs[h];
                    if (string.IsNullOrEmpty(temp_min) && string.IsNullOrEmpty(temp_max)) {
                        continue;
                    }

                    if (!string.IsNullOrEmpty(temp_min)) {
                        double min_value = 0;
                        if (!double.TryParse(temp_min, out min_value)) {
                            throw new CoreException("规格档限定值必须是数值: Spec = {0}, Param = {1}, Min = {2}", spec_name, H[h], temp_min);
                        }
                        min = min_value;
                    }
                    if (!string.IsNullOrEmpty(temp_max)) {
                        double max_value = 0;
                        if (!double.TryParse(temp_max, out max_value)) {
                            throw new CoreException("规格档限定值必须是数值: Spec = {0}, Param = {1}, Max = {2}", spec_name, H[h], temp_max);
                        }
                        max = max_value;
                    }
                    if (min == null && max == null) {
                        continue;
                    }

                    spec.Add(H[h], new SpecRange() { min = min, max = max });
                }

                if (spec.Count > 0) {
                    this.Specs.Add(spec_name, spec);
                }
            }
            return null;
        }

        public string check(NodeConfig node_data) {
            string spec_name = "";
            NodeConfig nconfig_result = null;
            for (int i = 0, len = node_data.configs.Count; i < len; i++) {
                NodeConfig data_i = node_data.configs[i];
                //
                if (string.IsNullOrEmpty(data_i.param)) {
                    continue;
                }
                if (data_i.param.ToUpper() == "SPEC") {
                    spec_name = (string)data_i.value;
                } else if (data_i.param.ToUpper() == "SPEC-RESULT") {
                    nconfig_result = data_i;
                }

                if (!string.IsNullOrEmpty(spec_name) && nconfig_result != null) {
                    break;
                }
            }

            if (string.IsNullOrEmpty(spec_name)) {
                return null;
            }
            if (!this.Specs.ContainsKey(spec_name)) {
                return "未找到指定的规格名称[" + spec_name + "]";
            }
            //
            Dictionary<string, SpecRange> spec = this.Specs[spec_name];
            StringBuilder sbResults = new StringBuilder();
            if (node_data.configs == null || node_data.configs.Count == 0) {
                return null;
            }
            for (int i = 0, len = node_data.configs.Count; i < len; i++) {
                NodeConfig data_i = node_data.configs[i];
                if (!data_i.data || string.IsNullOrEmpty(data_i.param)) {
                    continue;
                }

                string out_of_spec_msg = "";
                if (!data_i.param.Contains(",")) {
                    out_of_spec_msg = this.check(spec, data_i.param, data_i.value);
                } else {
                    if (data_i.value == null || data_i.value.GetType() != typeof(string)) {
                        throw new CoreException("参数[{0}]与数据不一致", data_i.param);
                    }
                    string[] PARAMS = data_i.param.Split(',');
                    string[] DATA = ((string)data_i.value).Split(',');
                    if (DATA == null || DATA.Length != PARAMS.Length) {
                        throw new CoreException("参数[{0}]与数据[{1}]不一致", data_i.param, data_i.value);
                    }
                    for (int j = 0, len_j = PARAMS.Length; j < len_j; j++) {
                        string key_j = PARAMS[j];
                        string data_j = DATA[j];
                        double value_j = 0;
                        if (!double.TryParse(data_j, out value_j)) {
                            throw new CoreException("参数[{0}]中包括非数值数据[{1}]", data_i.param, data_i.value);
                        }
                        string out_of_spec_msg_j = this.check(spec, key_j, value_j);
                        if (!string.IsNullOrEmpty(out_of_spec_msg_j)) {
                            out_of_spec_msg += (string.IsNullOrEmpty(out_of_spec_msg) ? "" : ";") + out_of_spec_msg_j;
                        }
                    }
                }

                if (!string.IsNullOrEmpty(out_of_spec_msg)) {
                    sbResults.Append(
                        (sbResults.Length > 0 ? "," : "") + out_of_spec_msg);
                }
            }
            //
            string spec_result = sbResults.Length == 0 ? "" : sbResults.ToString();
            if (nconfig_result != null) {
                nconfig_result.value = "\"" + spec_result + "\"";
            }
            if (!string.IsNullOrEmpty(spec_result)) {
                spec_result = "[SPEC = " + spec_name + "]," + spec_result;
            }
            return spec_result;
        }

        string check(Dictionary<string, SpecRange> spec, string key, object _value) {
            if (!spec.ContainsKey(key)) {
                return "";
            } else if(_value.GetType() != typeof(double)){
                throw new CoreException("参数[{0}]不是数值类型", key);
            }
            //
            SpecRange specRange = spec[key];
            double value = (double)_value;
            if (specRange.min != null && value < specRange.min) {
                return string.Format("[{2}: {0:0.000} < {1:0.000}]", value, specRange.min, key);
            } else if (specRange.max != null && value > specRange.max) {
                return string.Format("[{2}: {0:0.000} > {1:0.000}]", value, specRange.max, key);
            } else {
                return "";
            }
        }
    }
}
